auto-docs: Update Cloud API spec#71
Conversation
📝 WalkthroughWalkthroughThis PR extends the Redpanda API docs with network update as a first-class long-running operation. The controlplane API now defines a Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
🤖 Redpanda/cloud-controlplane API structural change detectedStructural change detailsAdded (1)
Powered by Bump.sh |
ℹ️ Redpanda/cloud-dataplane API content change detectedNo structural change, nothing to display. Powered by Bump.sh |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cloud-controlplane/cloud-controlplane.yaml`:
- Around line 6367-6380: The OpenAPI requestBody schema for NetworkUpdate
declares a required field "network" but does not define properties or a $ref;
update the NetworkUpdate schema used in the requestBody to either (a) include a
properties object that defines "network" (with its correct type or object
schema) or (b) replace the inline schema with a $ref to the existing Network
update model, ensuring "network" is properly declared, or (c) if this PATCH only
uses path parameters, remove the requestBody.required and the "network"
requirement entirely; look for the NetworkUpdate schema block and the
requestBody definition to apply the change.
- Around line 4356-4365: The new UpdateNetworkMetadata and
UpdateNetworkOperation types were added but not wired into the generic operation
unions; update the union types so v1.Operation can carry TYPE_UPDATE_NETWORK:
add an UpdateNetworkMetadata branch to OperationMetadata (or the equivalent
metadata union) and add an UpdateNetworkResponse/UpdateNetworkOperation branch
to OperationResponse (or the equivalent response union) so the generic
operations endpoints can represent TYPE_UPDATE_NETWORK using
UpdateNetworkMetadata and UpdateNetworkOperation.
- Around line 6356-6366: Remove the duplicate path item
/v1/networks/{network.id} by moving its patch operation (operationId:
NetworkService_UpdateNetwork) under the existing /v1/networks/{id} path and
delete the /v1/networks/{network.id} entry; also rename the path parameter from
name: network.id to name: id and ensure the parameter remains in: path,
required: true with schema type: string so the merged /v1/networks/{id} contains
the patch operation and a single canonical path parameter.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6096f9b7-088b-4f11-b71b-94a3dd9b0846
📒 Files selected for processing (2)
cloud-controlplane/cloud-controlplane.yamlcloud-dataplane/cloud-dataplane.yaml
| UpdateNetworkMetadata: | ||
| description: Resource describing an in-progress UpdateNetwork Operation. | ||
| title: UpdateNetworkMetadata | ||
| type: object | ||
| UpdateNetworkOperation: | ||
| description: UpdateNetworkOperation is the response of the update network rpc. | ||
| properties: | ||
| operation: | ||
| $ref: '#/components/schemas/v1.Operation' | ||
| type: object |
There was a problem hiding this comment.
Wire update-network into the generic operation unions.
UpdateNetworkMetadata and UpdateNetworkOperation are added here, but v1.Operation still cannot represent a TYPE_UPDATE_NETWORK operation in the generic operations endpoints because OperationMetadata lacks the UpdateNetworkMetadata branch and OperationResponse has no UpdateNetworkResponse branch at all.
Minimal wiring to add
OperationMetadata:
oneOf:
+ - allOf:
+ - properties:
+ '`@type`':
+ description: Fully qualified protobuf type name of the underlying response, prefixed with `type.googleapis.com/`.
+ enum:
+ - type.googleapis.com/redpanda.api.controlplane.v1.UpdateNetworkMetadata
+ type: string
+ - $ref: '`#/components/schemas/UpdateNetworkMetadata`'
+ UpdateNetworkResponse:
+ properties:
+ network:
+ $ref: '`#/components/schemas/Network`'
+ type: object
+
OperationResponse:
oneOf:
+ - allOf:
+ - properties:
+ '`@type`':
+ description: Fully qualified protobuf type name of the underlying response, prefixed with `type.googleapis.com/`.
+ enum:
+ - type.googleapis.com/redpanda.api.controlplane.v1.UpdateNetworkResponse
+ type: string
+ - $ref: '`#/components/schemas/UpdateNetworkResponse`'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cloud-controlplane/cloud-controlplane.yaml` around lines 4356 - 4365, The new
UpdateNetworkMetadata and UpdateNetworkOperation types were added but not wired
into the generic operation unions; update the union types so v1.Operation can
carry TYPE_UPDATE_NETWORK: add an UpdateNetworkMetadata branch to
OperationMetadata (or the equivalent metadata union) and add an
UpdateNetworkResponse/UpdateNetworkOperation branch to OperationResponse (or the
equivalent response union) so the generic operations endpoints can represent
TYPE_UPDATE_NETWORK using UpdateNetworkMetadata and UpdateNetworkOperation.
| /v1/networks/{network.id}: | ||
| patch: | ||
| description: Update a Redpanda network. | ||
| operationId: NetworkService_UpdateNetwork | ||
| parameters: | ||
| - description: ID of the network. | ||
| in: path | ||
| name: network.id | ||
| required: true | ||
| schema: | ||
| type: string |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
python - <<'PY'
import re
from collections import defaultdict
from pathlib import Path
text = Path("cloud-controlplane/cloud-controlplane.yaml").read_text()
in_paths = False
paths = []
for line in text.splitlines():
if line.strip() == "paths:":
in_paths = True
continue
if in_paths and re.match(r'^\S', line):
break
m = re.match(r'^ (/[^:]+):\s*$', line)
if in_paths and m:
paths.append(m.group(1))
normalized = defaultdict(list)
for path in paths:
normalized[re.sub(r'\{[^}]+\}', '{}', path)].append(path)
for key, variants in sorted(normalized.items()):
if len(variants) > 1:
print(key)
for variant in variants:
print(f" - {variant}")
PYRepository: redpanda-data/api-docs
Length of output: 522
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="cloud-controlplane/cloud-controlplane.yaml"
echo "=== Find /v1/networks/{id} path block ==="
rg -n --fixed-string ' /v1/networks/{id}:' "$FILE" -n || true
python - <<'PY'
from pathlib import Path
import re
p=Path("cloud-controlplane/cloud-controlplane.yaml")
lines=p.read_text().splitlines()
# find indices for the two path keys
targets=[" /v1/networks/{id}:"," /v1/networks/{network.id}:"]
for t in targets:
idx=[i for i,l in enumerate(lines) if l.strip()==t.strip()]
print(t, "count", len(idx), "indices", idx[:5])
if idx:
i=idx[0]
# print from a bit before to a bit after
start=max(0,i-5); end=min(len(lines), i+60)
print("\n--- Context for", t, "lines", start+1, "-", end, "---")
for k in range(start,end):
print(f"{k+1:>6} {lines[k]}")
PY
echo "=== Find all operations directly under those two path keys (method lines) ==="
python - <<'PY'
from pathlib import Path
import re
FILE=Path("cloud-controlplane/cloud-controlplane.yaml")
lines=FILE.read_text().splitlines()
def collect_methods(path_key):
methods=[]
# find line with exact key
idx=None
for i,l in enumerate(lines):
if l.strip()==path_key.strip():
idx=i
break
if idx is None:
return methods
# scan until next top-level path key (2 spaces indent, starts with /)
for j in range(idx+1,len(lines)):
l=lines[j]
if re.match(r'^ /[^:]+:\s*$', l.strip()):
break
m=re.match(r'^\s{4}([a-z]+):\s*$', l) # 4 spaces then http method
if m:
methods.append(m.group(1))
return methods
print("methods for /v1/networks/{id}:", collect_methods(" /v1/networks/{id}:"))
print("methods for /v1/networks/{network.id}:", collect_methods(" /v1/networks/{network.id}:"))
PYRepository: redpanda-data/api-docs
Length of output: 6784
🌐 Web query:
OpenAPI 3 duplicate/conflicting path templates different parameter names {id} vs {network.id} validator behavior
💡 Result:
In the OpenAPI 3 specification, paths that share the same hierarchy but use different parameter names in their templates (such as /users/{id} and /users/{network.id}) are considered identical and are strictly invalid [1][2][3]. The OpenAPI Specification explicitly states: "Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical" [1][3]. Because OpenAPI tooling normalizes these templates by treating the placeholder (the text inside the braces) as a generic segment, both {id} and {network.id} are effectively reduced to the same internal signature (e.g., /users/{}). Validator behavior typically includes the following: 1. Invalid Specification: Most linters and schema validators will flag this as an error because the structure is ambiguous and violates the specification's uniqueness requirements [4]. 2. Tooling Failure: Code generators and diffing tools often fail when they encounter these paths because they cannot distinguish between the two templates, leading to errors like "Two path items have the same signature" [4]. 3. Ambiguous Routing: If a validator fails to catch this, actual API routing becomes ambiguous. Since the specification considers them identical, there is no standardized behavior for how an API server or client should resolve which path to use, and it is left to the individual implementation [1][2]. To resolve this issue, you must use consistent parameter names across identical path structures or restructure your API to ensure the paths themselves are distinct (e.g., /users/{id} vs /networks/{network.id}/users/{id}) [5][4].
Citations:
- 1: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.4.md
- 2: https://spec.openapis.org/oas/v3.2.0.html
- 3: https://swagger.io/specification/
- 4: Two path items have the same signature OpenAPITools/openapi-diff#468
- 5: Ordering of matches when no path is concrete OAI/OpenAPI-Specification#2356
🌐 Web query:
OpenAPI path parameter name constraints allow dots '.' in {parameterName}
💡 Result:
In OpenAPI, dots '.' are allowed in the path parameter name (the identifier inside { }), as the spec does not restrict the parameter-name characters to exclude '.'. [1] What OpenAPI does restrict is the content/value of a path parameter: the path parameter value MUST NOT contain any unescaped “generic syntax” characters described by RFC3986: forward slashes (/), question marks (?), or hashes (#). This restriction is about the parameter value at runtime, not the name/identifier inside the curly braces. [2][3] So {user.name} as a template name is permitted by the OpenAPI rules, but the actual value substituted for {user.name} cannot include unescaped '/', '?', or '#'. [1][2]
Citations:
- 1: Path Templating: is there a restriction on the path parameter name? OAI/OpenAPI-Specification#1969
- 2: https://swagger.io/specification/
- 3: "path parameters MUST NOT contain any unescaped “generic syntax” characters" OAI/OpenAPI-Specification#2804
Merge /v1/networks/{network.id} into the existing /v1/networks/{id} path item (remove duplicate templated path)
/v1/networks/{network.id} conflicts with /v1/networks/{id}: OpenAPI does not allow two path items with the same hierarchy but different templated names ({network.id} vs {id}), since they’re treated as the same templated path signature by validators/generators. Move the patch operation under /v1/networks/{id} and rename the path parameter to name: id.
/v1/networks/{network.id}:
patch:
description: Update a Redpanda network.
operationId: NetworkService_UpdateNetwork
parameters:
- description: ID of the network.
in: path
name: network.id
required: true
schema:
type: string🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cloud-controlplane/cloud-controlplane.yaml` around lines 6356 - 6366, Remove
the duplicate path item /v1/networks/{network.id} by moving its patch operation
(operationId: NetworkService_UpdateNetwork) under the existing /v1/networks/{id}
path and delete the /v1/networks/{network.id} entry; also rename the path
parameter from name: network.id to name: id and ensure the parameter remains in:
path, required: true with schema type: string so the merged /v1/networks/{id}
contains the patch operation and a single canonical path parameter.
| requestBody: | ||
| content: | ||
| application/json: | ||
| schema: | ||
| description: Resource describing an Update Network. | ||
| required: | ||
| - network | ||
| title: NetworkUpdate | ||
| type: object | ||
| description: |- | ||
| NetworkUpdate | ||
|
|
||
| Resource describing an Update Network. | ||
| required: true |
There was a problem hiding this comment.
Define the PATCH payload instead of requiring an undeclared field.
The request schema marks network as required, but it defines neither properties.network nor a $ref. That leaves clients/codegen with a required key of unspecified shape. Either reference a real update schema here or drop the body requirement if this operation is path-only.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cloud-controlplane/cloud-controlplane.yaml` around lines 6367 - 6380, The
OpenAPI requestBody schema for NetworkUpdate declares a required field "network"
but does not define properties or a $ref; update the NetworkUpdate schema used
in the requestBody to either (a) include a properties object that defines
"network" (with its correct type or object schema) or (b) replace the inline
schema with a $ref to the existing Network update model, ensuring "network" is
properly declared, or (c) if this PATCH only uses path parameters, remove the
requestBody.required and the "network" requirement entirely; look for the
NetworkUpdate schema block and the requestBody definition to apply the change.
This PR updates the OpenAPI spec file for the Cloud API.
Triggered by commit: 81be7a0dc7e6a0131324a36d05ac0cdee63fa330